package com.asia.execl;

import java.io.File;
import java.io.FileInputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;

public class ImportExcel<T> {

    Class<T> clazz;

    public ImportExcel(Class<T> clazz) {
        this.clazz = clazz;
    }

    public Collection<T> importExcel(File file, String... pattern) {
        Collection<T> dist = new ArrayList<T>();
        try {
            /**
             * �෴��õ����÷���
             */
            // �õ�Ŀ��Ŀ��������е��ֶ��б� 
            Field[] fields = clazz.getDeclaredFields();
            // �����б���Annotation���ֶΣ�Ҳ�������?����ݵ��ֶ�,���뵽һ��map��
            Map<String, Method> fieldMap = new HashMap<String, Method>();
            // ѭ����ȡ�����ֶ�
            for (Field field : fields) {
                // �õ������ֶ��ϵ�Annotation
                ExcelAnnotation excelAnnotation = field.getAnnotation(ExcelAnnotation.class);
                // ����ʶ��Annotationd
                if (excelAnnotation != null) {
                    String fieldName = field.getName();
                    // ����������Annotation���ֶε�Setter����
                    String setMethodName = "set" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
                    // ������õ�method
                    Method setMethod = clazz.getMethod(setMethodName, new Class[]{field.getType()});
                    // �����method��Annotaion������Ϊkey������
                    fieldMap.put(excelAnnotation.exportName(), setMethod);
                }
            }

            /**
             * excel�Ľ�����ʼ
             */
            // �������File����ΪFileInputStream;
            FileInputStream inputStream = new FileInputStream(file);
            // �õ�������
            HSSFWorkbook book = new HSSFWorkbook(inputStream);
            // �õ���һҳ
            HSSFSheet sheet = book.getSheetAt(0);
            // �õ���һ���������
            Iterator<Row> row = sheet.rowIterator();
            // �õ���һ�У�Ҳ���Ǳ����� 
            /********************************************
             * �������
             *  Workbook book = null;
             try {
             book = new XSSFWorkbook(excelFile);
             } catch (Exception ex) {
             book = new HSSFWorkbook(new FileInputStream(excelFile));
             }
             */

            Row titleRow = row.next();
            // �õ���һ�е�������
            Iterator<Cell> cellTitle = titleRow.cellIterator();
            // ��������������ݷ��뵽һ��map��
            Map<Integer, String> titleMap = new HashMap<Integer, String>();
            // �ӱ����һ�п�ʼ
            int i = 0;
            // ѭ���������е���
            while (cellTitle.hasNext()) {
                Cell cell = (Cell) cellTitle.next();
                String value = cell.getStringCellValue();
                titleMap.put(i, value);
                i++;
            }

            /**
             * ����������
             */
            while (row.hasNext()) {
                // �����µĵ�һ��
                Row rown = row.next();
                // �е�������
                Iterator<Cell> cellBody = rown.cellIterator();
                // �õ��������ʵ��
                T tObject = clazz.newInstance();
                // ����һ�е���
                int col = 0;
                while (cellBody.hasNext()) {
                    Cell cell = (Cell) cellBody.next();
                    // ����õ����еĶ�Ӧ�ı���
                    String titleString = titleMap.get(col++);
                    // �����һ�еı�������е�ĳһ�е�Annotation��ͬ����ô����ô���ĵ�set������������ֵ
                    if (fieldMap.containsKey(titleString)) {
                        Method setMethod = fieldMap.get(titleString);
                        //�õ�setter�����Ĳ���
                        Type[] types = setMethod.getGenericParameterTypes();
                        //ֻҪһ������
                        String xclass = String.valueOf(types[0]);
                        //�жϲ�������
                        if ("class java.lang.String".equals(xclass)) {
                            setMethod.invoke(tObject, cell.getStringCellValue());
                        } else if ("class java.util.Date".equals(xclass)) {
                            setMethod.invoke(tObject, cell.getDateCellValue());
                        } else if ("class java.lang.Boolean".equals(xclass)) {
                            Boolean boolName = true;
                            if ("��".equals(cell.getStringCellValue())) {
                                boolName = false;
                            }
                            setMethod.invoke(tObject, boolName);
                        } else if ("class java.lang.Integer".equals(xclass)) {
                            setMethod.invoke(tObject, new Integer(String.valueOf((int) cell.getNumericCellValue())));
                        } else if ("class java.lang.Long".equals(xclass)) {
                            setMethod.invoke(tObject, new Long(cell.getStringCellValue()));
                        } else {
                            //
                        }
                    }
                }
                dist.add(tObject);
            }

        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
            return null;
        }
        return dist;
    }

    public static void main(String[] args) {
        ImportExcel<TestVo> test = new ImportExcel<TestVo>(TestVo.class);
        File file = new File("D:\\testOne.xls");
        List<TestVo> results = (List<TestVo>) test.importExcel(file);
//        SimpleDateFormat simpleDateFormat;  
//        simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");    
        for (TestVo testVo : results) {
            System.out.println(testVo.getName() + "\t" + testVo.getSex() + "\t" + testVo.getBrith());
        }
    }
}
